﻿using E0XPayService.Utils.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace E0XPayService.Utils
{
    public class E0XUtils
    {
        static Log logger = LogFactory.GetLogger("CallLog");

        // 生成签名
        private static string GenerateSign(Dictionary<string,string> inputDict)
        {
            var signContent = string.Join("&", inputDict.Where(x => !string.IsNullOrWhiteSpace(x.Value)).OrderBy(x => x.Key).Select(x => x.Key + "=" + x.Value));
            var stringSignTemp = signContent + "&key=" + E0XConfig._apiKey;

            string sign = MD5Helper.GetMD5Hash(stringSignTemp);
            return sign;
        }

        public static E0XPayResponse WxchatPayJSPay(int amount, string attach)
        {
            var result = new E0XPayResponse();
            var orderNo = StringExtension.GetPrimaryKey();

            var log = new CallLog() { OperationName = "WxchatPayJSPay" };
            log.OtherInfo = string.Format("orderNo:{0},amount:{1},reserved:{2}", orderNo, amount, attach);

            try
            {
                if (amount <= 0)
                {
                    result.ErrorMsg = "总金额不能为【0】！";
                }
                else
                {
                    Dictionary<string, string> inputDict = new Dictionary<string, string>();

                    inputDict.Add("mch_id", E0XConfig._mchId); //商户号
                    inputDict.Add("subject", E0XConfig._body); //商品标题
                    inputDict.Add("attach", attach);
                    inputDict.Add("out_trade_no", StringExtension.GetPrimaryKey());//用户订单号
                    inputDict.Add("total_fee", amount.ToString());
                    inputDict.Add("notify_url", E0XConfig._notify_url);//异步通知地址
                    inputDict.Add("return_url", E0XConfig._callback_url);//同步通知地址
                    inputDict.Add("pt", "XIAOWEI");
                    inputDict.Add("channel", "JSPAY");//公众号支付

                    inputDict = inputDict.OrderBy(x => x.Key).ToDictionary(x => x.Key, x => x.Value);
                    var sign = GenerateSign(inputDict);
                    inputDict.Add("sign", sign);

                    log.RequestDetail = JSONHelper.Serialize(inputDict);

                    var url = E0XConfig._apiurl + "/pay/order";
                    var web = new WebUtils();
                    var response = web.DoPost(url, inputDict, E0XConfig._input_charset);

                    //var response = @"{""status"":0,""message"":""\u521b\u5efa\u652f\u4ed8\u8ba2\u5355\u6210\u529f"",""data"":{""out_trade_no"":""1567737045009"",""code_url"":""https:\/\/v.e0x.cn\/pay\/wxpay?mch_id=10069&out_trade_no=1567737045009&sign=4adb68d30990f04e0a9ce2d720a2b892"",""total_fee"":1}}";

                    log.ResponseDetail = response;
                    log.OperationEnd = DateTime.Now;

                    var responseObj = JsonConvert.DeserializeObject<JObject>(response);
                    if (responseObj["status"].ToString() == "0")
                    {
                        var data = responseObj["data"].ToString();
                        var dataObj = JsonConvert.DeserializeObject<JObject>(data);

                        result.IsSuccess = true;
                        result.Content = new JObject();
                        result.Content.Add("success", true);
                        result.Content.Add("codeurl", dataObj["code_url"].ToString());
                    }
                    else
                    {
                        result.ErrorMsg = responseObj["message"].ToString();
                        result.ErrorCode = responseObj["status"].ToString();
                    }
                }

                if (!result.IsSuccess)
                {
                    LogError(new CallErrorLog(JSONHelper.Serialize(log), result.ErrorCode, result.ErrorMsg));
                }
            }
            catch (Exception ex)
            {
                LogError(new CallErrorLog(JSONHelper.Serialize(log), ex));

                result.ErrorMsg = ex.Message;
                result.ErrorCode = "-999";
            }

            log.ResultInfo = JSONHelper.Serialize(result);
            LogInfo(log);

            return result;
        }

        private static void LogInfo(CallLog log)
        {
            Task.Factory.StartNew(() =>
            {
                try { logger.Info(log); } catch { }
            });
        }

        private static void LogError(CallErrorLog log)
        {
            Task.Factory.StartNew(() =>
            {
                try { logger.Error(log); } catch { }
            });
        }


        public static bool NorifyContentCheckSign(string notifyInput)
        {
            var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(notifyInput);
            if (!dict.ContainsKey("sign")) return false;
            var sign = dict["sign"];
            dict.Remove("sign");

            var sign2 = GenerateSign(dict);
            return sign == sign2;
        }
    }

    public class E0XPayResponse
    {
        public bool IsSuccess { get; set; }

        public string ErrorMsg { get; set; }
        public string ErrorCode { get; set; }

        public JObject Content { get; set; }
    }
}